package org.acme.cluster.lock;

import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/***
 * 使用db实现分布式锁
 */
@Data
public class DbLock implements Lock {

    Logger logger = LoggerFactory.getLogger(getClass());

    private DataSource dataSource;

    private Connection connection;

    private boolean autoCommit;

    private String sql = "select * from db_lock where id = 1 for update";

    private PreparedStatement preparedStatement;

    public DbLock(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Override
    public void lock() throws Exception {
        this.connection = this.getDataSource().getConnection();
        this.autoCommit = connection.getAutoCommit();
        this.connection.setAutoCommit(false);
        this.preparedStatement = this.connection.prepareStatement(this.sql);
        this.preparedStatement.execute();
    }

    @Override
    public void unlock() {
        if (this.preparedStatement != null) {
            try {
                this.preparedStatement.close();
            } catch (SQLException e) {
                logger.error(e.getMessage(), e);
            }
        }
        if (this.connection != null) {
            try {
                this.connection.commit();
            } catch (SQLException e) {
                logger.error(e.getMessage(), e);
            }
            try {
                this.connection.setAutoCommit(this.autoCommit);
            } catch (SQLException e) {
                logger.error(e.getMessage(), e);
            }
            try {
                this.connection.close();
            } catch (SQLException e) {
                logger.error(e.getMessage(), e);
            }
        }
    }
}
